﻿#include <unistd.h>                                                                
#include <stdlib.h>                                                                
#include <errno.h>                                                                 
#include <string.h>                                                                
#include <stdio.h>   
#include <iconv.h>
#include <dlfcn.h>
#include <netinet/in.h>    // for sockaddr_in
#include <wait.h>
#include <sys/socket.h>    // for socket
#include <sys/types.h>
#include <sys/stat.h>
#include <memory.h>
#include <arpa/inet.h>
#include "common.h"
#include "email.h"

/*将str1字符串中第一次出现的str2字符串替换成str3*/
void replaceFirst(char *str1, char *str2, char *str3)
{
	char str4[strlen(str1) + 1];
	char *p;
	strcpy(str4, str1);
	if ((p = strstr(str1, str2)) != NULL)/*p指向str2在str1中第一次出现的位置*/
	{
		while (str1 != p&&str1 != NULL)/*将str1指针移动到p的位置*/
		{
			str1++;
		}
		str1[0] = '\0';/*将str1指针指向的值变成/0,以此来截断str1,舍弃str2及以后的内容，只保留str2以前的内容*/
		strcat(str1, str3);/*在str1后拼接上str3,组成新str1*/
		strcat(str1, strstr(str4, str2) + strlen(str2));/*strstr(str4,str2)是指向str2及以后的内容(包括str2),strstr(str4,str2)+strlen(str2)就是将指针向前移动strlen(str2)位，跳过str2*/
	}
}
/*将str1出现的所有的str2都替换为str3*/
void replace(char *str1, char *str2, char *str3)
{
	while (strstr(str1, str2) != NULL)
	{
		replaceFirst(str1, str2, str3);
	}
}
/*截取src字符串中,从下标为start开始到end-1(end前面)的字符串保存在dest中(下标从0开始)*/
void substring(char *dest, char *src, int start, int end)
{
	int i = start;
	if (start>strlen(src))return;
	if (end>strlen(src))
		end = strlen(src);
	while (i<end)
	{
		dest[i - start] = src[i];
		i++;
	}
	dest[i - start] = '\0';
	return;
}
/*返回src中下标为index的字符*/
char charAt(char *src, int index)
{
	char *p = src;
	int i = 0;
	if (index<0 || index>strlen(src))
		return 0;
	while (i<index)i++;
	return p[i];
}
/*返回str2第一次出现在str1中的位置(下表索引),不存在返回-1*/
int indexOf(char *str1, const char *str2)
{
	char *p = str1;
	int i = 0;
	p = strstr(str1, str2);
	if (p == NULL)
		return -1;
	else{
		while (str1 != p)
		{
			str1++;
			i++;
		}
	}
	return i;
}
/*返回str1中最后一次出现str2的位置(下标),不存在返回-1*/
int lastIndexOf(char *str1, const char *str2)
{
	char *p = str1;
	int i = 0, len = strlen(str2);
	p = strstr(str1, str2);
	if (p == NULL)return -1;
	while (p != NULL)
	{
		for (; str1 != p; str1++)i++;
		p = p + len;
		p = strstr(p, str2);
	}
	return i;
}
/*删除str左边第一个非空白字符前面的空白字符(空格符和横向制表符)*/
void ltrim(char *str)
{
	int i = 0, j, len = strlen(str);
	while (str[i] != '\0')
	{
		if (str[i] != 32 && str[i] != 9)break;/*32:空格,9:横向制表符*/
		i++;
	}
	if (i != 0)
	for (j = 0; j <= len - i; j++)
	{
		str[j] = str[j + i];/*将后面的字符顺势前移,补充删掉的空白位置*/
	}
}
/*删除str最后一个非空白字符后面的所有空白字符(空格符和横向制表符)*/
void rtrim(char *str)
{
	char *p = str;
	int i = strlen(str) - 1;
	while (i >= 0)
	{
		if (p[i] != 32 && p[i] != 9)break;
		i--;
	}
	str[++i] = '\0';
}
/*删除str两端的空白字符*/
void trim(char *str)
{
	ltrim(str);
	rtrim(str);
}

//代码转换:从一种编码转为另一种编码
int code_convert(char *from_charset, char *to_charset, char *inbuf, size_t inlen, char *outbuf, size_t outlen)
{
	iconv_t cd;
	char **pin = &inbuf;
	char **pout = &outbuf;

	cd = iconv_open(to_charset, from_charset);
	if (cd == 0) return -1;
	memset(outbuf, 0, outlen);
	if (iconv(cd, pin, &inlen, pout, &outlen) == -1) return -1;
	iconv_close(cd);
	return 0;
}

int u2g(char *inbuf, size_t inlen, char *outbuf, size_t outlen)
{
	return code_convert("utf-8", "gb2312", inbuf, inlen, outbuf, outlen);
}

int g2u(char *inbuf, size_t inlen, char *outbuf, size_t outlen)
{
	return code_convert("gb2312", "utf-8", inbuf, inlen, outbuf, outlen);
}

/**
* 生成校验码(不计算前后空格)
* @param str
* @return
*/
int getCode(char* str) {
	//char out[1024] = { '\0' };
	//u2g(str, strlen(str), out, 1024);

	int sum = 0;
	int i;
	for (i = 0; i < strlen(str); i++) {
		sum = sum + str[i];
	}
	sum = sum & 0xff;
	return sum;
}

void Get_Info(char* Flag, char* Info, char* recvBytes)    //获取单引号里内容
{
	int index = 0;
	short i = 0;
	char *p = strstr(recvBytes, Flag);
	if (p == NULL)
	{
		Info = "";
	}
	else
	{
		char *q = recvBytes;
		while (q != p)
		{
			q++;
			index++;
		}

		index = index + strlen(Flag) + 1;
		if (recvBytes[index] == '\'')
			Info = "";
		else
		{
			do
			{
				Info[i++] = recvBytes[index++];
			} while (recvBytes[index] != '\'');
		}
	}
}

int sendLoginRequest(int client_socket, char* hwid)
{
	char send_str[256] = { '\0' };
	char content_str[256] = { '\0' };
	int check_code;
	sprintf(content_str, "login type='ZBT7620n' id='%s' device='sw001' version='1.0' user='admin' password='admin'",hwid);
	check_code = getCode(content_str);
	sprintf(send_str, "%s %s check='%d' %s", TAG_START, content_str, check_code, TAG_END);

	if (send(client_socket, send_str, strlen(send_str), 0) < 0)
	{
		printf("发送登录请求失败!\n");
		return -1;
	}
	else
	{
		return 1;
	}
}

void sendGetAPInfoResponse(int client_socket)
{
    char send_str[4096] = { '\0' };
	char content_str[2048] = { '\0' };
	int check_code;
	AP_INFO ap_info;
	get_wireless_config(&ap_info);
	sprintf(content_str, "AP_Info tflag='0' tp1='%d' ch1='%d' ssid1='%s' encry1='%d' key1='%s' tp2='%d' ch2='%d' ssid2='%s' encry2='%d' key2='%s'",\
			     ap_info.tp1, ap_info.ch1, ap_info.ssid1, ap_info.encry1, ap_info.key1, \
			     ap_info.tp2, ap_info.ch2, ap_info.ssid2, ap_info.encry2, ap_info.key2 );
	check_code = getCode(content_str);
	sprintf(send_str, "%s %s check='%d' %s", TAG_START, content_str, check_code, TAG_END);

	if (send(client_socket, send_str, strlen(send_str), 0) < 0)
	{
		printf("发送获取AP信息响应失败!\n");
	}
}

void recvAPConfigRequest(char* recv_buffer, AP_INFO* ap_info)
{
    //单频AP的情况
    char tp1_str[8] = { '\0' };
    Get_Info("tp1=", tp1_str, recv_buffer);
    ap_info->tp1 = atoi(tp1_str);
    char ch1_str[8] = { '\0' };
    Get_Info("ch1=", ch1_str, recv_buffer);
    ap_info->ch1 = atoi(ch1_str);
    Get_Info("ssid1=", ap_info->ssid1, recv_buffer);
    char encry1_str[8] = { '\0' };
    Get_Info("encry1=", encry1_str, recv_buffer);
    ap_info->encry1 = atoi(encry1_str);
    Get_Info("key1=", ap_info->key1, recv_buffer);
    Get_Info("ssid2=", ap_info->ssid2, recv_buffer);
    char encry2_str[8] = { '\0' };
    Get_Info("encry2=", encry2_str, recv_buffer);
    ap_info->encry2 = atoi(encry2_str);
    Get_Info("key2=", ap_info->key2, recv_buffer);
}

void sendStaListResponse(int client_socket)
{
	char send_str[4096] = { '\0' };
	char content_str[3072] = { '\0' };
	char cache[3072];
	int i  = 0;
	int check_code;
	struct sta_mac_list *p = NULL;
	struct sta_mac_list *head = NULL;
	head = get_wlan_station_mac_list();
	memset(cache,'\0', sizeof(cache));
	if (head)
	{
		for(p = head,i = 1; p != NULL; p = p->next,i++)
		{
			memset(content_str,'\0', sizeof(content_str));
			sprintf(content_str, " mac%d='%s'", i, p->stamac);
			strcat(cache, content_str);
		}
	}
	memset(content_str,'\0', sizeof(content_str));
	printf("cache is %s\n",cache);
	sprintf(content_str, "STA_Info sta_num='%d'%s",i, cache);
	check_code = getCode(content_str);
	sprintf(send_str, "%s %s check='%d' %s", TAG_START, content_str, check_code, TAG_END);

	if (send(client_socket, send_str, strlen(send_str), 0) < 0)
	{
		printf("发送获取AP信息响应失败!\n");
	}
}
/* 获取无线station信息 */
struct sta_mac_list *get_wlan_station_mac_list()
{
	FILE * rfd = NULL;
	struct sta_mac_list *head =NULL, *p = NULL;
	rfd = popen(OPENWRT_GET_STSTION_MAC, "r");
	while (!feof(rfd))
	{
		p = (struct sta_mac_list *)malloc(sizeof(struct sta_mac_list));
		if (p)
		{
			fgets(p->stamac, 20, rfd);
			p->next = head;
			head = p;
		}
	}
	return head;
}

/* 获取无线配置 */
void get_wireless_config(AP_INFO *ap_info)
{
	FILE *rfd = NULL;
	char cache[256];
	rfd = popen(OPENWRT_GET_TXPOWER, "r");
	if (rfd)
	{
		memset(cache,'\0', sizeof(cache));
		fgets(cache, sizeof(cache), rfd);
		if (strstr(cache, "Entry not found"))
			ap_info->tp1 = 0;
		else
			ap_info->tp1 = atoi(cache);
		pclose(rfd);
		rfd = NULL;
	}
	rfd = popen(OPENWRT_GET_CHANNEL, "r");
	if (rfd)
	{
		memset(cache,'\0', sizeof(cache));
		fgets(cache, sizeof(cache), rfd);
		if(strstr(cache, "auto"))
			ap_info->ch1 = 0;
		else
			ap_info->ch1 = atoi(cache);
		pclose(rfd);
		rfd = NULL;
	}
	rfd = popen(OPENWRT_GET_SSID, "r");
	if (rfd)
	{
		fgets(ap_info->ssid1, 64, rfd);
		pclose(rfd);
		rfd = NULL;
	}
	rfd = popen(OPENWRT_GET_ENCRYPTION, "r");
	if (rfd)
	{
		fgets(cache, sizeof(cache), rfd);
		if (strstr(cache, "none"))
			ap_info->encry1 = 0;
		else if (strstr(cache, "web"))
			ap_info->encry1 = 1;
		else if (strstr(cache, "wpapsk"))
			ap_info->encry1 = 2;
		else if (strstr(cache, "wpa2psk"))
			ap_info->encry1 = 3;
		pclose(rfd);
		rfd = NULL;
	}
	if (ap_info->encry1 != 0)
	{
		rfd = popen(OPENWRT_GET_ENKEY, "r");
		if (rfd)
		{
			fgets(ap_info->key1, 256, rfd);
			pclose(rfd);
			rfd = NULL;
		}
	}


	rfd = popen(OPENWRT_GET_TXPOWER_ONE, "r");
	if (rfd)
	{
		memset(cache,'\0', sizeof(cache));
		fgets(cache, sizeof(cache), rfd);
		if (strstr(cache, "Entry not found"))
			ap_info->tp2 = 0;
		else
			ap_info->tp2 = atoi(cache);
		pclose(rfd);
		rfd = NULL;
	}
	rfd = popen(OPENWRT_GET_CHANNEL_ONE, "r");
	if (rfd)
	{
		memset(cache,'\0', sizeof(cache));
		fgets(cache, sizeof(cache), rfd);
		if(strstr(cache, "auto"))
			ap_info->ch2 = 0;
		else
			ap_info->ch2 = atoi(cache);
		pclose(rfd);
		rfd = NULL;
	}
	rfd = popen(OPENWRT_GET_SSID_ONE, "r");
	if (rfd)
	{
		memset(cache,'\0', sizeof(cache));
		fgets(cache, 64, rfd);
		if (strstr(cache, "Entry not found"))
			memcpy(ap_info->ssid2, cache, 64);
		pclose(rfd);
		rfd = NULL;
	}
	rfd = popen(OPENWRT_GET_ENCRYPTION_ONE, "r");
	if (rfd)
	{
		fgets(cache, sizeof(cache), rfd);
		if (strstr(cache, "none") || strstr(cache, "Entry not found"))
			ap_info->encry2 = 0;
		else if (strstr(cache, "web"))
			ap_info->encry2 = 1;
		else if (strstr(cache, "wpapsk"))
			ap_info->encry2 = 2;
		else if (strstr(cache, "wpa2psk"))
			ap_info->encry2 = 3;
		pclose(rfd);
		rfd = NULL;
	}
	if (ap_info->encry2 != 0)
	{
		rfd = popen(OPENWRT_GET_ENKEY_ONE, "r");
		if (rfd)
		{
			memset(cache,'\0', sizeof(cache));
			fgets(cache, 256, rfd);
			if (strstr(cache, "Entry not found"))
				memcpy(ap_info->key2, cache, 256);
			pclose(rfd);
			rfd = NULL;
		}
	}
}
/* 修改无线配置 */
 void set_wireless_config(AP_INFO ap_info)
{
	FILE *rfd = NULL, *wfd = NULL;
	char set_cmd_buffer[4096] = {'\0'};	
	char cache[512] = {'\0'};
	int i = 0;
	memset(cache, '\0', sizeof(cache));
	sprintf(cache, "%s = %d\n",OPENWRT_SET_TXPOWER ,ap_info.tp1);
	strcat(set_cmd_buffer, cache);
	memset(cache, '\0', sizeof(cache));
	if (ap_info.ch1 == 0)
		sprintf(cache, "%s = auto\n",OPENWRT_SET_CHANNEL);
	else
		sprintf(cache, "%s = %d\n",OPENWRT_SET_CHANNEL,ap_info.ch1);
	strcat(set_cmd_buffer, cache);
	memset(cache, '\0', sizeof(cache));
	sprintf(cache, "%s = %s\n",OPENWRT_SET_SSID,ap_info.ssid1);
	strcat(set_cmd_buffer, cache);

	if (ap_info.encry1 == 0)
	{	
		memset(cache, '\0', sizeof(cache));
		sprintf(cache, "%s = none\n",OPENWRT_SET_ENCRYPTION);
		strcat(set_cmd_buffer, cache);
	}
	else
	{
		memset(cache, '\0', sizeof(cache));
		if (ap_info.encry1 == 1)
			sprintf(cache, "%s = wep\n",OPENWRT_SET_ENCRYPTION);
		if (ap_info.encry1 == 2)
			sprintf(cache, "%s = wpapsk\n",OPENWRT_SET_ENCRYPTION);
		if (ap_info.encry1 == 3)
			sprintf(cache, "%s = wpa2psk\n",OPENWRT_SET_ENCRYPTION);
		strcat(set_cmd_buffer, cache);

		sprintf(cache, "%s = %s\n",OPENWRT_SET_ENKEY, ap_info.key1);
		strcat(set_cmd_buffer, cache);
		memset(cache, '\0', sizeof(cache));
	}
	
	if (ap_info.ssid2)
	{
		rfd = popen(OPENWRT_GET_SSID_ONE, "r");
		if (NULL != rfd)
		{
			fgets(cache, 20, rfd);
			pclose(rfd);
		}
		if (strstr(cache, "Entry not found"))
		{
			memset(cache, '\0', sizeof(cache));
			sprintf(cache, "%s\n", OPENWRT_ADD_INTERFACE);
			strcat(set_cmd_buffer, cache);

			memset(cache, '\0', sizeof(cache));
			sprintf(cache, "%s\n", OPENWRT_SET_DEF_IFACE_ONE);
			strcat(set_cmd_buffer, cache);
		}
		memset(cache, '\0', sizeof(cache));
		sprintf(cache, "%s = %s\n",OPENWRT_SET_SSID_ONE,ap_info.ssid1);
		strcat(set_cmd_buffer, cache);
		if (ap_info.encry1 == 0)
		{	
			memset(cache, '\0', sizeof(cache));
			sprintf(cache, "%s = none\n",OPENWRT_SET_ENCRYPTION_ONE);
			strcat(set_cmd_buffer, cache);
		}
		else
		{
			memset(cache, '\0', sizeof(cache));
			if (ap_info.encry1 == 1)
				sprintf(cache, "%s = wep\n",OPENWRT_SET_ENCRYPTION_ONE);
			if (ap_info.encry1 == 2)
				sprintf(cache, "%s = wpapsk\n",OPENWRT_SET_ENCRYPTION_ONE);
			if (ap_info.encry1 == 3)
				sprintf(cache, "%s = wpa2psk\n",OPENWRT_SET_ENCRYPTION_ONE);
			strcat(set_cmd_buffer, cache);

			sprintf(cache, "%s = %s\n",OPENWRT_SET_ENKEY_ONE, ap_info.key1);
			strcat(set_cmd_buffer, cache);
			memset(cache, '\0', sizeof(cache));
		}
	}
	else
	{}
	for(i = 0; i <3; i++){
		wfd = fopen(CONFIG_CMD_SHELL_FILE, "w+");
		if(wfd)
			break;
	}
	printf("set cmd is \n %s\n", set_cmd_buffer);
	if(wfd)
	{
		fputs(set_cmd_buffer, wfd);
		chmod(CONFIG_CMD_SHELL_FILE, 7777);
		memset(cache, '\0', sizeof(cache));
		sprintf(cache,"%s &", CONFIG_CMD_SHELL_FILE);
	//	sys(cache);
	}
}

